package com.dingtalk.yuanhua_spring_project.task;

import com.dingtalk.yuanhua_spring_project.dto.InstanceInfoDTO;
import com.dingtalk.yuanhua_spring_project.pojo.Employee;
import com.dingtalk.yuanhua_spring_project.pojo.Instance;
import com.dingtalk.yuanhua_spring_project.repository.EmployeeRepository;
import com.dingtalk.yuanhua_spring_project.repository.InstanceRepository;
import com.dingtalk.yuanhua_spring_project.service.impl.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class DailyTask {
    private static final Logger logger = LoggerFactory.getLogger(DailyTask.class);
    @Autowired
    private DingTalkYiDaimpl dingTalkYiDaimpl;
    @Autowired
    private DingTalkStorageimpl dingTalkStorageimpl;
    @Autowired
    private DingTalkAccessimpl dingTalkAccessimpl;
    @Autowired
    private DingTalkDingPanimpl dingTalkDingPanimpl;
    @Autowired
    private DingTalkYiDa1_0impl dingTalkYiDa1_0impl;
    @Autowired
    private InstanceRepository instanceRepository;
    @Autowired
    private EmployeeRepository employeeRepository;
    @Value("${app_key}")
    private String app_key;
    @Value("${app_secret}")
    private String app_secret;
    @Value("${app_agentid}")
    private String app_agentid;
    @Value("${app_id}")
    private String app_id;
    @Value("${union_id}")
    private String union_id;
    @Value("${app_type}")
    private String app_type;
    @Value("${system_token}")
    private String system_token;
    @Value("${user_id}")
    private String user_id;
    @Value("${space_id}")
    private String space_id;
    @Value("${xiangmu_ruku_folder_name}")
    private String xiangmu_ruku_folder_name;
    @Value("${xiangmu_ruku_form_id}")
    private String xiangmu_ruku_form_id;
    @Value("${xiangmu_ruku_jijin_name}")
    private String xiangmu_ruku_jijin_name;
    @Value("${xiangmu_ruku_xiangmu_jiancheng}")
    private String xiangmu_ruku_xiangmu_jiancheng;
    @Value("${xiangmu_ruku_fileattach}")
    private String xiangmu_ruku_fileattach;
    @Value("${xiangmu_ruku_otherfileattach}")
    private String xiangmu_ruku_otherfileattach;
    //项目立项
    @Value("${xiangmu_lixiang_folder_name}")
    private String xiangmu_lixiang_folder_name;
    @Value("${xiangmu_lixiang_form_id}")
    private String xiangmu_lixiang_form_id;
    @Value("${xiangmu_ruku_xiangmu_name}")
    private String xiangmu_ruku_xiangmu_name;
    @Value("${xiangmu_lixiang_fileattach}")
    private String xiangmu_lixiang_fileattach;
    @Value("${xiangmu_lixiang_jijin_name}")
    private String xiangmu_lixiang_jijin_name;
    @Value("${xiangmu_lixiang_xiangmu_jiancheng}")
    private String xiangmu_lixiang_xiangmu_jiancheng;
    @Value("${toujue_yugoutong_folder_name}")
    private String toujue_yugoutong_folder_name;
    @Value("${toujue_yugoutong_form_id}")
    private String toujue_yugoutong_form_id;
    @Value("${toujue_yugoutong_jijin_name}")
    private String toujue_yugoutong_jijin_name;
    @Value("${toujue_yugoutong_xiangmu_jiancheng}")
    private String toujue_yugoutong_xiangmu_jiancheng;
    @Value("${toujue_yugoutong_fileattach}")
    private String toujue_yugoutong_fileattach;
    @Value("${xiangmu_lixiang_xiangmu_name}")
    private String xiangmu_lixiang_xiangmu_name;
    @Value("${toujue_yugoutong_xiangmu_name}")
    private String toujue_yugoutong_xiangmu_name;
    @Value("${toujue_baogao_folder_name}")
    private String toujue_baogao_folder_name;
    @Value("${toujue_baogao_form_id}")
    private String toujue_baogao_form_id;
    @Value("${toujue_baogao_jijin_name}")
    private String toujue_baogao_jijin_name;
    @Value("${toujue_baogao_xiangmu_name}")
    private String toujue_baogao_xiangmu_name;
    @Value("${toujue_baogao_xiangmu_jiancheng}")
    private String toujue_baogao_xiangmu_jiancheng;
    @Value("${toujue_baogao_fileattach}")
    private String toujue_baogao_fileattach;
    @Value("${touzi_hetong_folder_name}")
    private String touzi_hetong_folder_name;
    @Value("${touzi_hetong_form_id}")
    private String touzi_hetong_form_id;
    @Value("${touzi_hetong_jijin_name}")
    private String touzi_hetong_jijin_name;
    @Value("${touzi_hetong_xiangmu_name}")
    private String touzi_hetong_xiangmu_name;
    @Value("${touzi_hetong_fileattach}")
    private String touzi_hetong_fileattach;
    @Value("${touzi_hetong_xiangmu_jiancheng}")
    private String touzi_hetong_xiangmu_jiancheng;
    @Value("${fukuan_tongzhi_folder_name}")
    private String fukuan_tongzhi_folder_name;
    @Value("${fukuan_tongzhi_form_id}")
    private String fukuan_tongzhi_form_id;
    @Value("${fukuan_tongzhi_jijin_name}")
    private String fukuan_tongzhi_jijin_name;
    @Value("${fukuan_tongzhi_xiangmu_name}")
    private String fukuan_tongzhi_xiangmu_name;
    @Value("${fukuan_tongzhi_xiangmu_jiancheng}")
    private String fukuan_tongzhi_xiangmu_jiancheng;
    @Value("${fukuan_tongzhi_fileattach}")
    private String fukuan_tongzhi_fileattach;
    @Value("${touzi_jueyi_folder_name}")
    private String touzi_jueyi_folder_name;
    @Value("${touzi_jueyi_form_id}")
    private String touzi_jueyi_form_id;
    @Value("${touzi_jueyi_jijin_name}")
    private String touzi_jueyi_jijin_name;
    @Value("${touzi_jueyi_xiangmu_name}")
    private String touzi_jueyi_xiangmu_name;
    @Value("${touzi_jueyi_xiangmu_jiancheng}")
    private String touzi_jueyi_xiangmu_jiancheng;
    @Value("${touzi_jueyi_fileattach}")
    private String touzi_jueyi_fileattach;
    @Value("${qita_wenjian_buchong_folder_name}")
    private String qita_wenjian_buchong_folder_name;
    @Value("${qita_wenjian_buchong_form_id}")
    private String qita_wenjian_buchong_form_id;
    @Value("${qita_wenjian_buchong_jijin_name}")
    private String qita_wenjian_buchong_jijin_name;
    @Value("${qita_wenjian_buchong_xiangmu_name}")
    private String qita_wenjian_buchong_xiangmu_name;
    @Value("${qita_wenjian_buchong_xiangmu_jiancheng}")
    private String qita_wenjian_buchong_xiangmu_jiancheng;
    @Value("${qita_wenjian_buchong_fileattach}")
    private String qita_wenjian_buchong_fileattach;
    @Value("${zibiao}")
    private String zibiao;
    @Value("${tuichu_baogao_folder_name}")
    private String tuichu_baogao_folder_name;
    @Value("${tuichu_baogao_form_id}")
    private String tuichu_baogao_form_id;
    @Value("${tuichu_baogao_jijin_name}")
    private String tuichu_baogao_jijin_name;
    @Value("${tuichu_baogao_xiangmu_name}")
    private String tuichu_baogao_xiangmu_name;
    @Value("${tuichu_baogao_xiangmu_jiancheng}")
    private String tuichu_baogao_xiangmu_jiancheng;
    @Value("${tuichu_baogao_fileattach}")
    private String tuichu_baogao_fileattach;


    @Scheduled(cron = "0 0 23 * * ?") // 每天晚上11点执行
    public void executeDailyTask() {
        try {
            logger.info("执行表单下载任务");
            //1. 自动化任务 ， 2. 其他的表单信息， 3.添加权限 ， 4.表单和数据库进行联动，没有的再去查
            String accessToken = dingTalkAccessimpl.getAccessToken();
            // 获取所有文件夹信息
            Map<String, Map<String, String>> folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
            System.out.println(accessToken);

            // 定义表单配置
            List<Map<String, String>> formConfigs = new ArrayList<>();
            formConfigs.add(Map.of(
                    "formId", xiangmu_ruku_form_id,
                    "folderName", xiangmu_ruku_folder_name,
                    "jijinNameKey", xiangmu_ruku_jijin_name,
                    "xiangmuNameKey", xiangmu_ruku_xiangmu_name,
                    "jianchengNameKey", xiangmu_ruku_xiangmu_jiancheng,
                    "fileAttachKey", xiangmu_ruku_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", xiangmu_lixiang_form_id,
                    "folderName", xiangmu_lixiang_folder_name,
                    "jijinNameKey", xiangmu_lixiang_jijin_name,
                    "xiangmuNameKey", xiangmu_lixiang_xiangmu_name,
                    "jianchengNameKey", xiangmu_lixiang_xiangmu_jiancheng,
                    "fileAttachKey", xiangmu_lixiang_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", toujue_yugoutong_form_id,
                    "folderName", toujue_yugoutong_folder_name,
                    "jijinNameKey", toujue_yugoutong_jijin_name,
                    "xiangmuNameKey", toujue_yugoutong_xiangmu_name,
                    "jianchengNameKey", toujue_yugoutong_xiangmu_jiancheng,
                    "fileAttachKey", toujue_yugoutong_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", toujue_baogao_form_id,
                    "folderName", toujue_baogao_folder_name,
                    "jijinNameKey", toujue_baogao_jijin_name,
                    "xiangmuNameKey", toujue_baogao_xiangmu_name,
                    "jianchengNameKey", toujue_baogao_xiangmu_jiancheng,
                    "fileAttachKey", toujue_baogao_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", touzi_hetong_form_id,
                    "folderName", touzi_hetong_folder_name,
                    "jijinNameKey", touzi_hetong_jijin_name,
                    "xiangmuNameKey", touzi_hetong_xiangmu_name,
                    "jianchengNameKey", touzi_hetong_xiangmu_jiancheng,
                    "zibiao", zibiao,
                    "fileAttachKey", touzi_hetong_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", fukuan_tongzhi_form_id,
                    "folderName", fukuan_tongzhi_folder_name,
                    "jijinNameKey", fukuan_tongzhi_jijin_name,
                    "xiangmuNameKey", fukuan_tongzhi_xiangmu_name,
                    "jianchengNameKey", fukuan_tongzhi_xiangmu_jiancheng,
                    "zibiao", zibiao,
                    "fileAttachKey", fukuan_tongzhi_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", touzi_jueyi_form_id,
                    "folderName", touzi_jueyi_folder_name,
                    "jijinNameKey", touzi_jueyi_jijin_name,
                    "xiangmuNameKey", touzi_jueyi_xiangmu_name,
                    "jianchengNameKey", touzi_jueyi_xiangmu_jiancheng,
                    "fileAttachKey", touzi_jueyi_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", qita_wenjian_buchong_form_id,
                    "folderName", qita_wenjian_buchong_folder_name,
                    "jijinNameKey", qita_wenjian_buchong_jijin_name,
                    "xiangmuNameKey", qita_wenjian_buchong_xiangmu_name,
                    "jianchengNameKey", qita_wenjian_buchong_xiangmu_jiancheng,
                    "fileAttachKey", qita_wenjian_buchong_fileattach
            ));
            formConfigs.add(Map.of(
                    "formId", tuichu_baogao_form_id,
                    "folderName", tuichu_baogao_folder_name,
                    "jijinNameKey", tuichu_baogao_jijin_name,
                    "xiangmuNameKey", tuichu_baogao_xiangmu_name,
                    "jianchengNameKey", tuichu_baogao_xiangmu_jiancheng,
                    "fileAttachKey", tuichu_baogao_fileattach
            ));

            // 处理每个表单
            for (Map<String, String> formConfig : formConfigs) {
                logger.info("处理表单: {}", folderList.get("folderName"));
                processForm(accessToken, formConfig.get("formId"), formConfig.get("jijinNameKey"), formConfig.get("xiangmuNameKey"), formConfig.get("jianchengNameKey"), formConfig.get("folderName"),formConfig.get("zibiao"),formConfig.get("fileAttachKey"), folderList);
            }

            // 查询 has_permission 为 false 的员工
            List<Employee> employeesWithNoPermission = employeeRepository.findEmployeesWithNoPermission();
            // 调用赋予权限的方法
            grantPermissions(accessToken, employeesWithNoPermission, folderList);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void processForm(String accessToken, String formId, String jijinNameKey, String xiangmuNameKey, String jianchengNameKey, String folderName, String zibiao,String fileAttachKey, Map<String, Map<String, String>> folderList) {
        try {
            List<String> instanceIdList = dingTalkYiDaimpl.getInstanceIdList(accessToken, this.app_type, formId, this.user_id, this.system_token);
            // 获取数据库中已存在的 instanceId 列表
            List<InstanceInfoDTO> existingInstance = instanceRepository.findAllInstanceInfo();
            for (String instanceId : instanceIdList) {
                try {
                    if(!(Objects.equals(folderName, "付款通知书") || Objects.equals(folderName, "投资决议及投票") || Objects.equals(folderName, "其他补充文件"))){
                        // 如果 instanceId 已经存在，跳过当前循环
                        if (existingInstance.stream().anyMatch(existing -> existing.getInstanceId().equals(instanceId))) {
                            continue;
                        }
                    }

                    // 项目名称根据表单及附件ID来确认
                    Map<String, ?> instance = dingTalkYiDaimpl.getInstance(accessToken, instanceId);
                    logger.info("处理实例: {}", instanceId);
                    if (instance == null){
                        continue;
                    }
                    String modifiedTimeGMT = (String) instance.get("modifiedTime");
                    String modifiedTime = modifiedTimeGMT.substring(0, 10); // 提取前10个字符，即 "yyyy-MM-dd"
                    // 判断如果不是null，流程继续，否则跳过
                    List<String> jsonStrings = new ArrayList<>();

                    // 分割 fileAttachKey
                    String[] fileAttachKeys = fileAttachKey.split(",");


                    for (String key : fileAttachKeys) {
                        if(zibiao  != null){
                            List<Map<String, Object>> zibiaoList = (List<Map<String, Object>>) instance.get(zibiao);
                            for (Map<String, Object> value : zibiaoList){
                                if (value.get(key) != null) {
                                    jsonStrings.add(value.get(key).toString());
                                }
                            }
                        }
                        String jsonString = (String) instance.get(key.trim());
                        if (jsonString != null && !jsonString.isEmpty()) {
                            jsonStrings.add(jsonString);
                        }
                    }

                    if (jsonStrings.isEmpty()) {
                        continue;
                    }

                    Object jijin_name_component_obj = instance.get(jijinNameKey);
                    String jijin_name_component = null;
                    if (jijin_name_component_obj instanceof String) {
                        jijin_name_component = ((String) jijin_name_component_obj).trim();
                    }

                    String jijin_name = jijin_name_component;
                    if (jijin_name_component != null && jijinNameKey.contains("ass")) {
                        ObjectMapper objectMapper = new ObjectMapper();
                        // 使用正则表达式提取 title 字段的值
                        jijin_name_component = jijin_name_component.replaceAll("^\"|\"$", "").replace("\\", "").trim();
                        List<Map<String, Object>> jijin_name_component_list = objectMapper.readValue(jijin_name_component, new TypeReference<List<Map<String, Object>>>() {});
                        String title = (String) jijin_name_component_list.getFirst().get("title");
                        if (title != null) {
                            jijin_name = title;
                        }
                    }
                    logger.info("{} 的基金名称 : {}", folderName, jijin_name);
                    String xiangmu_name = (String) instance.get(xiangmuNameKey);
                    logger.info("{} 的项目名称 : {}", folderName, xiangmu_name);
                    String jiancheng_name = (String) instance.get(jianchengNameKey);
                    logger.info("{} 的项目简称 : {}", folderName, jiancheng_name);
                    String projectName = xiangmu_name;
                    String foldername = jiancheng_name + "-" + folderName;
                    String folder_list = "/" + jijin_name + "/" + xiangmu_name + "/" + folderName;
                    if (instanceRepository.existsByFolderListAndModifiedTime(folder_list,  modifiedTime)) {
                        continue; // 如果存在，跳过当前循环
                    }

                    // 检查 existingInstance 中是否存在匹配的记录
                    if (!isInstanceMatched(existingInstance, jijin_name, jiancheng_name, projectName)) {
                        continue; // 如果匹配，跳过当前循环
                    }

                    // 如果在folderList中找不到jijin_name，就在parentid:0创建文件夹，文件夹名称为jijin_name，重新获取所有文件夹信息
                    if (!folderList.containsKey("/" + jijin_name)) {
                        dingTalkStorageimpl.addFolder(jijin_name, space_id, "0", accessToken);
                        folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
                    }
                    String jijinFolderId = folderList.get("/" + jijin_name).get("id");
                    if (!folderList.containsKey("/" + jijin_name + "/" + xiangmu_name)) {
                        dingTalkStorageimpl.addFolder(xiangmu_name, space_id, jijinFolderId, accessToken);
                        folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
                    }
                    String xiangmuFolderId = folderList.get("/" + jijin_name + "/" + xiangmu_name).get("id");
                    if (!folderList.containsKey("/" + jijin_name + "/" + xiangmu_name + "/" + foldername)) {
                        // 防止有重名项目简称，所以校验path路径
                        dingTalkStorageimpl.addFolder(foldername, space_id, xiangmuFolderId, accessToken);
                        folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
                    }
                    String FileSaveFolderId = folderList.get("/" + jijin_name + "/" + xiangmu_name + "/" + foldername).get("uuid");

                    // 找到所有以 employeeField ，根据表单来找出所有的项目成员
                    List<ArrayList<?>> employeeList = instance.entrySet().stream()
                            .filter(entry -> entry.getKey().startsWith("employeeField") && entry.getKey().endsWith("id"))
                            .map(Map.Entry::getValue)
                            .filter(value -> value instanceof ArrayList)
                            .map(value -> (ArrayList<?>) value)
                            .collect(Collectors.toList());
                    // 拆分 employeeList 中的值到 new_employeeList
                    List<Object> new_employeeList = employeeList.stream()
                            .flatMap(ArrayList::stream) // 将每个 ArrayList 展开成一个流
                            .collect(Collectors.toList());

                    // 去重
                    new_employeeList = new_employeeList.stream()
                            .distinct() // 去重
                            .collect(Collectors.toList());
                    System.out.println(new_employeeList);

                    ObjectMapper objectMapper = new ObjectMapper();

                    // 处理每个 jsonString
                    for (String jsonString : jsonStrings) {
                        try {
                            List<Map<String, Object>> fileList = objectMapper.readValue(jsonString, new TypeReference<List<Map<String, Object>>>() {});

                            // 提取 downloadUrl 和文件名
                            List<String> downloadUrls = fileList.stream()
                                    .map(file -> (String) file.get("downloadUrl"))
                                    .collect(Collectors.toList());
                            List<String> downloadFileNames = fileList.stream()
                                    .map(file -> (String) file.get("name"))
                                    .collect(Collectors.toList());

                            // 下载并上传文件
                            for (int i = 0; i < downloadUrls.size(); i++) {
                                try {
                                    logger.info("文件下载名称{}", downloadUrls.get(i));
                                    String fileSavePath = dingTalkYiDa1_0impl.getDownloadUrl(accessToken, downloadUrls.get(i), this.system_token, this.user_id, this.app_type, downloadFileNames.get(i));
                                    dingTalkStorageimpl.GetFileUploadInfoByDentryId(accessToken, FileSaveFolderId, fileSavePath, insertTimeBeforeExtension(downloadFileNames.get(i),  modifiedTime));
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    // 检查 Instance 是否已经存在
                    if (!instanceRepository.existsByInstanceIdAndModifiedTime(instanceId, modifiedTime)) {
                        Instance instanceEntity = new Instance();
                        instanceEntity.setInstanceId(instanceId);
                        instanceEntity.setJijinName(jijin_name);
                        instanceEntity.setJianchengName(jiancheng_name);
                        instanceEntity.setFolderList("/" + jijin_name + "/" + jiancheng_name + "/" + foldername);
                        instanceEntity.setInvested(true);
                        instanceEntity.setModifiedTime(modifiedTime);
                        instanceEntity.setProjectName(projectName); // 设置 projectName
                        instanceRepository.save(instanceEntity);
                    }

                    for (Object employee : new_employeeList) {
                        // 检查 Employee 是否已经存在
                        if (!employeeRepository.existsByJijinNameAndProjectNameAndEmployeeId(jijin_name, projectName, employee.toString())) {
                            Employee employeeEntity = new Employee();
                            employeeEntity.setJijinName(jijin_name);
                            employeeEntity.setProjectName(projectName);
                            employeeEntity.setJianchengName(jiancheng_name);
                            employeeEntity.setEmployeeId(employee.toString());
                            employeeEntity.setHasPermission(false); // 初始化为 false
                            employeeRepository.save(employeeEntity);
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void grantPermissions(String accessToken, List<Employee> employeesWithNoPermission, Map<String, Map<String, String>> folderList) throws Exception {
        for (Employee employee : employeesWithNoPermission) {
            String jijin_name = employee.getJijinName();
            String xiangmu_name = employee.getProjectName();
            String folderPath = "/" + jijin_name + "/" + xiangmu_name;

            if (folderList.containsKey(folderPath)) {
                String uuid = folderList.get(folderPath).get("uuid");
                dingTalkStorageimpl.addPermission(accessToken, employee.getEmployeeId(), uuid);
                // 更新 has_permission 为 true
                employee.setHasPermission(true);
                employeeRepository.save(employee);
            } else {
                logger.error("Folder path " + folderPath + " not found in folderList for employee ID: " + employee.getEmployeeId());
            }
        }
    }

    private boolean isInstanceMatched(List<InstanceInfoDTO> existingInstances, String jijinName, String jianchengName, String projectName) {
        for (InstanceInfoDTO existingInstance : existingInstances) {
            if (
                    existingInstance.getJijinName().equals(jijinName) &&
                            existingInstance.getJianchengName().equals(jianchengName) &&
                            existingInstance.getProjectName().equals(projectName)) {
                return true;
            }
        }
        return false;
    }

    private String insertTimeBeforeExtension(String fileName, String modifiedTime) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex == -1) {
            // 如果没有找到扩展名，直接在文件名末尾添加 _time
            return fileName + "_" + modifiedTime;
        }
        String namePart = fileName.substring(0, lastDotIndex);
        String extensionPart = fileName.substring(lastDotIndex);
        return namePart + "_" + modifiedTime + extensionPart;
    }
}
